<template>
  <div>
    <div class="msg-input-wrapper">
      <div v-if="isReplyMsg" class="reply-message-wrapper">
        <div class="reply-message-close" @tap="removeReplyMsg">
          <Icon color="#929299" :iconStyle="{ fontWeight: '200' }" :size="13" type="icon-guanbi" />
        </div>
        ｜
        <div class="reply-title">{{ t('replyText') }}</div>
        <div class="reply-noFind" v-if="replyMsg && replyMsg.idClient == 'noFind'">
          {{ t('replyNotFindText') }}
        </div>
        <div class="reply-message" v-else>
          <div class="reply-to">
            <Appellation
              :account="replyMsg.from"
              :team-id="scene === 'team' ? to : ''"
              color="#929299"
              :fontSize="13"
            ></Appellation>
          </div>
          :
          <div v-if="replyMsg.type === 'text'" class="reply-msg-content">
            <message-one-line :text="replyMsg.body"></message-one-line>
          </div>
          <div v-else>{{ '[' + REPLY_MSG_TYPE_MAP[replyMsg.type] + ']' }}</div>
        </div>
      </div>
      <!-- <div class="msg-button-group">
          <div @tap="handleEmojiVisible" class="msg-input-button">
            <Icon :size="20" type="icon-biaoqing" />
          </div>
          <div class="msg-input-button" @tap="handleSendImageMsg">
            <div v-if="sendingImg" class="msg-input-button msg-input-loading">
              <image class="loading" src="https://yiyong-qa.netease.im/yiyong-static/statics/uniapp-vue2-h5/static/icons/icon-a-Frame8.png"></image>
            </div>
            <div v-else>
              <Icon :size="20" type="icon-tupian" />
            </div>
          </div>
          <div class="msg-input-button" @tap="handleSetting">
            <Icon type="icon-shezhi" :size="20" />
          </div>
        </div> -->
      <div class="msg-input">
        <!-- 当从表情面包切换到文字输入时，直接唤起键盘，ios 会存在input框消失的情况，故此处需要用EmojiInput兼容下 -->
        <div @click="onClickEmojiInput" v-if="showEmojiInput && !isIOSWeb" class="input-emoji">
          <div v-if="inputText" class="input-text">{{ inputText }}</div>
          <div v-else class="input-placeholder">{{ placeholder }}</div>
        </div>
        <div class="msg-input-wrap" v-else>
          <div
            v-if="audio.visible"
            class="recorder"
            :class="{ 'recorder-active': audio.recording }"
            @touchstart.stop.prevent="startRecord"
            @touchend.stop.prevent="endRecord"
          >
            {{ audio.recording ? '松开 发送' : '按住 说话' }}
          </div>
          <!-- <textarea
            v-else
            id="msg-input"
            class="msg-input-input"
            auto-height
            :maxlength="-1"
            :placeholder="placeholder"
            v-model="inputText"
            :focus="isFocus"
            :disabled="isTeamMute"
            :confirm-hold="true"
            cursor-spacing="20"
            adjust-position="true"
            confirm-type="send"
            disable-default-padding
            @confirm="handleSendTextMsg"
            @blur="handleInputBlur"
            @focus="handleInputFocus"
            @input="handleInput"
          /> -->
          <div v-else class="msg-input-inputs">
            <textarea
              id="msg-input"
              class="msg-input-input"
              auto-height
              :maxlength="-1"
              :placeholder="placeholder"
              v-model="inputText"
              :focus="isFocus"
              :disabled="isTeamMute"
              :confirm-hold="true"
              cursor-spacing="20"
              adjust-position="true"
              confirm-type="send"
              disable-default-padding
              @confirm="handleSendTextMsg"
              @blur="handleInputBlur"
              @focus="handleInputFocus"
              @input="handleInput"
            />
          </div>
        </div>

        <image
          class="img"
          v-if="!audio.visible"
          @tap="switchAudioKeyboard"
          mode="aspectFit"
          src="../../../static/icons/vioce.png"
        ></image>
        <image
          class="img"
          v-else
          @tap="switchAudioKeyboard"
          mode="aspectFit"
          src="../../../static/icons/keyword.png"
        ></image>
        <image
          class="img"
          @tap="showExt"
          mode="aspectFit"
          src="../../../static/icons/plus.png"
        ></image>
      </div>
      <div v-if="extVisible" class="msg-ext" @click.stop="() => {}">
        <view class="menu">
          <u-grid :col="4">
            <!-- <u-grid-item>
              <div class="item" @tap="showGoods">
                <image class="img" mode="aspectFit" src="../../../static/icons/goods.png"></image>
                <text class="text">商品链接</text>
              </div>
            </u-grid-item> -->
            <u-grid-item>
              <div class="item" @tap="handleSendImageMsg">
                <image class="img" mode="aspectFit" src="../../../static/icons/img.png"></image>
                <text class="text">图片</text>
              </div>
            </u-grid-item>
            <!-- <u-grid-item>
              <div class="item" @tap="sendTip">
                <image class="img" mode="aspectFit" src="../../../static/icons/tip.png"></image>
                <text class="text">提醒患者</text>
              </div>
            </u-grid-item> -->
          </u-grid>
        </view>

        <Face
          v-if="emojiVisible"
          @emojiClick="handleEmoji"
          @emojiDelete="handleEmojiDelete"
          @emojiSend="handleSendTextMsg"
        />
      </div>
    </div>
    <!-- <u-action-sheet
      :actions="goodsList"
      :title="goodsTitle"
      :show="goodsShow"
      @select="goodsSelect"
      @close="goodsShow = false"
      :closeOnClickOverlay="true"
      :safeAreaInsetBottom="true"
    ></u-action-sheet> -->
    <!-- <u-modal
      :show="sendShow"
      @confirm="sendConfirm"
      @close="sendShow = false"
      @cancel="sendShow = false"
      :buttonReverse="true"
      :showCancelButton="true"
      content="确定要向患者发送消息提醒吗?"
      :closeOnClickOverlay="true"
    ></u-modal> -->
    <UniPopup
      ref="popupRef"
      background-color="#ffffff"
      type="bottom"
      mask-background-color="rgba(0,0,0,0.4)"
      @change="onPopupChange"
    >
      <MentionMemberList :team-id="to"></MentionMemberList>
    </UniPopup>
    <div class="recordering" v-if="audio.recording">
      <div v-if="countdown" class="tip">{{ countdown }}秒后将停止录音</div>
      <div v-else class="img"></div>
    </div>
    <!-- <button @click="sendVideo">发送一条语音消息</button> -->
  </div>
</template>

<script lang="ts" setup>
import type { TMsgScene } from 'nim-web-sdk-ng/dist/NIM_MINIAPP_SDK/MsgServiceInterface'
import Face from './face.vue'
import Icon from '../../../components/Icon.vue'
import {
  ref,
  getCurrentInstance,
  computed,
  onUnmounted,
  onMounted,
  onBeforeMount
} from '../../../utils/transformVue'
import { events, REPLY_MSG_TYPE_MAP } from '../../../utils/constants'
import { emojiMap } from '../../../utils/emoji'
import { t } from '../../../utils/i18n'
// import { handleNoPermission } from '../../../utils/permission';
import { customNavigateTo } from '../../../utils/customNavigate'
import type { IMMessage } from '@xkit-yx/im-store'
import MessageOneLine from '../../../components/MessageOneLine.vue'
import { getUniPlatform } from '../../../utils'
// @ts-ignore
import UniPopup from '../../../uni_modules/uni-popup/components/uni-popup/uni-popup.vue'
import MentionMemberList from './mention-member-list.vue'
import { autorun } from 'mobx'
import Appellation from '../../../components/Appellation.vue'
import { getGoodsList, sendAdverseMessage, upload, uploadVideo } from '../../../api/index'
import store from '@/store/index'
import bus from '@/utils/bus'
import { sendNotice } from '../../../api/index'

// #ifdef H5
// import wx from 'weixin-js-sdk';
// import { hasUrl } from '@/utils/common';
const switchAudioKeyboard = () => {
  console.log(store.state.app.URLS)
  // const url = window.location.href;
  // const url = window.location.hash;
  // const url_key = hasUrl(url);
  let f = false
  console.log(store.state.app.URLS)
  for (let key in store.state.app.URLS) {
    if (store.state.app.URLS[key]) {
      f = true
      break
    }
  }
  if (f) {
    audio.value.visible = !audio.value.visible
    if (extVisible.value) {
      extVisible.value = !extVisible.value
    }
  } else {
    uni.showModal({
      content: '请关注公众号后重试',
      showCancel: false,
      success: function (res) {
        if (res.confirm) {
          console.log('用户点击确定')
        }
      }
    })
  }
}

const sendVideo = (id, duration) => {
  const obj = {
    type: 'video',
    body: id,
    duration: duration
    // body: 'https://web-ext-storage.dcloud.net.cn/uni-app/ForElise.mp3',
    // duration: 5000
  }
  const msg = '[发送了一段语音]'
  sendCustomMsg(obj, msg)
}

// import Recorder from 'js-audio-recorder';

// const recorder = ref(null);
// const recorderPermission = ref(false);

// onBeforeMount(() => {
//   recorder.value = new Recorder({
//     sampleBits: 8, // 采样位数，支持 8 或 16，默认是16
//     sampleRate: 11025, // 采样率，支持 11025、16000、22050、24000、44100、48000，根据浏览器默认值，我的chrome是48000
//     numChannels: 1 // 声道，支持 1 或 2， 默认是1
//     // compiling: false,(0.x版本中生效,1.x增加中)  // 是否边录边转换，默认是false
//   });
// });

// const switchAudioKeyboard = () => {
//   if (!recorderPermission.value) {
//     Recorder.getPermission().then(
//       () => {
//         console.log('录音授权通过');
//         recorderPermission.value = true;
//         audio.value.visible = !audio.value.visible;
//       },
//       (error) => {
//         uni.showModal({
//           title: '提示',
//           content: `${error.name} : ${error.message}`,
//           showCancel: false,
//           success: function (res) {
//             if (res.confirm) {
//               console.log('用户点击确定');
//             } else if (res.cancel) {
//               console.log('用户点击取消');
//             }
//           }
//         });
//         console.log(`${error.name} : ${error.message}`);
//       }
//     );
//   } else {
//     console.log('录音授权通过');
//     audio.value.visible = !audio.value.visible;
//   }
// };
// #endif

// #ifndef H5
const recorderManager = uni.getRecorderManager()
const innerAudioContext = uni.createInnerAudioContext()
innerAudioContext.autoplay = true

const switchAudioKeyboard = () => {
  audio.value.visible = !audio.value.visible
}
// #endif

const audio = ref({
  startTime: null,
  //语音录音中
  recording: false,
  //录音按钮展示
  visible: false
})

let RecorderTimer = null

const startTime = ref(0)

const otherStop = () => {
  store.commit('im/VIDEO_STOP')
  // bus.emit('im_video_stop_paly')
}
const countdown = ref(0)

const startRecord = () => {
  if (audio.value.recording) {
    return
  }
  console.log('开始录音')
  otherStop()
  if (RecorderTimer) {
    clearInterval(RecorderTimer)
    RecorderTimer = null
  }
  startTime.value = Date.now()
  console.time('record')
  let t = 0
  RecorderTimer = setInterval(() => {
    t++
    if (t === 60) {
      endRecord()
      clearInterval(RecorderTimer)
      RecorderTimer = null
    }
    if (t === 50) {
      countdown.value = 10
    }
    if (t > 50) {
      countdown.value = countdown.value - 1
    }
  }, 1000)
  audio.value.recording = true
  // #ifdef H5
  wx.startRecord()
  // #endif
  // #ifndef H5
  recorderManager.start({
    format: 'mp3'
  })
  // #endif
}

const endRecord = () => {
  if (!audio.value.recording) return

  // #ifndef H5
  recorderManager.stop()
  // #endif

  // #ifdef H5
  audio.value.recording = false
  console.log('录音结束')
  let endTime = Date.now()
  console.timeEnd('record')
  console.log(endTime - startTime.value)
  clearInterval(RecorderTimer)
  RecorderTimer = null
  let duration = endTime - startTime.value
  if (duration < 1000) {
    console.log('时间太短')
    uni.showToast({
      title: '录音时间太短',
      icon: 'none'
    })

    wx.stopRecord({
      success: function (res) {},
      complete: function () {
        startTime.value = 0
      }
    })
  } else {
    console.log('时间够了')
    wx.stopRecord({
      success: function (res) {
        console.log(res)
        // localId.value = res.localId;
        uploadVoice(res.localId).then((serverId) => {
          sendVideo(serverId, duration)
          uploadVideo(serverId, duration)
        })
      },
      complete: function () {
        startTime.value = 0
      }
    })
  }
  // #endif
}

const uploadVoice = (localId) => {
  return new Promise((resolve, reject) => {
    wx.uploadVoice({
      localId: localId, // 需要上传的音频的本地ID，由stopRecord接口获得
      isShowProgressTips: 1, // 默认为1，显示进度提示
      success: function (res) {
        console.log('上传成功', res)
        var serverId = res.serverId // 返回音频的服务器端ID
        resolve(serverId)
      }
    })
  })
}

type MentionedMember = { account: string; appellation: string }
const props = defineProps({
  scene: {
    type: String, // Assuming TMsgScene is a custom object type
    required: true
  },
  to: {
    type: String,
    required: true
  },
  replyMsgsMap: {
    type: Object,
    default: undefined
  }
})
const inputText = ref('')
const extVisible = ref(false)
const emojiVisible = ref(false)
const sendingImg = ref(false)
const uniPlatform = getUniPlatform()
const isAndroidApp = uni.getSystemInfoSync().platform == 'android' && uniPlatform == 'app'
const showEmojiInput = ref(false)
const isIOSWeb = uniPlatform === 'web' && uni.getSystemInfoSync().platform === 'ios'
// 回复消息相关
const isReplyMsg = ref(false)
const isFocus = ref(false)
const replyMsg = ref<IMMessage>({
  idClient: '',
  from: '',
  // @ts-ignore
  type: '',
  text: '',
  body: '',
  sessionId: ''
})
// @消息相关
const ctx = getCurrentInstance()
const popupRef = ref(null)
const selectedAtMembers = ref<MentionedMember[]>([])

// 群禁言
const isTeamMute = ref(false)
const placeholder = computed(() => {
  return isTeamMute.value ? t('teamMutePlaceholder') : t('chatInputPlaceHolder')
})

const goodsList = ref([])
const goodsTitle = '请选择您要发送的商品链接'
const goodsShow = ref(false)
// const showGoods = () => {
//   getGoodsList({
//     page: 1,
//     limit: 50
//   }).then((res) => {
//     if (res.data.list.length) {
//       goodsList.value = res.data.list.map((v) => {
//         v.name = v.productName
//         return v
//       })
//     } else {
//       goodsList.value = []
//     }
//     goodsShow.value = true
//   })
// }
// const goodsSelect = (e) => {
//   console.log(e)
//   const { id, productId, productName, linkUrl, picUrl, belong } = e
//   const obj = {
//     type: 'text',
//     body: linkUrl,
//     id,
//     productId,
//     productName,
//     linkUrl,
//     picUrl,
//     belong
//   }
//   const msg = '[发送了一个商品链接]'
//   sendCustomMsg(obj, msg)
// }

const showExt = () => {
  extVisible.value = !extVisible.value
  if (audio.value.visible) {
    audio.value.visible = !audio.value.visible
  }
}

const sendShow = ref(false)
// const sendTip = () => {
//   sendShow.value = true
// }
// const sendConfirm = () => {
//   let sessionId = uni.$UIKitStore.uiStore.selectedSession
//   const userinfo = JSON.parse(uni.getStorageSync('userInfo'))
//   sendShow.value = false
//   sendAdverseMessage({
//     patientId: sessionId.split('-')[1],
//     healthId: userinfo.userId,
//     healthName: userinfo.userName
//   })
//     .then((res) => {
//       uni.showToast({
//         title: '提醒患者成功!',
//         duration: 2000
//       })
//     })
//     .catch((e) => {})
// }

const onPopupChange = (e: any) => {
  uni.$emit(events.HANDLE_MOVE_THROUGH, e.value)
}

const handleMentionItemClick = (member: MentionedMember) => {
  // @ts-ignore
  ctx.refs.popupRef.close()
  uni.$emit(events.HANDLE_MOVE_THROUGH, false)
  const nickInTeam = member.appellation
  selectedAtMembers.value = [
    ...selectedAtMembers.value.filter((item) => item.account !== member.account),
    member
  ]
  const newInputText = inputText.value + nickInTeam + ' '
  // 更新input框的内容
  inputText.value = newInputText
}

const closePopup = () => {
  // @ts-ignore
  ctx.refs.popupRef.close()
}

const onClickEmojiInput = () => {
  showEmojiInput.value = false
  extVisible.value = false
  emojiVisible.value = false
  setTimeout(() => {
    isFocus.value = true
  }, 300)
}

const handleInputFocus = () => {
  if (extVisible.value) {
    extVisible.value = !extVisible.value
  }
  uni.$emit(events.ON_INPUT_FOCUS_CHANGE, true)
}

const handleInputBlur = () => {
  isFocus.value = false
  setTimeout(() => {
    uni.$emit(events.ON_SCROLL_BOTTOM)
  }, 300)
  uni.$emit(events.ON_INPUT_FOCUS_CHANGE, false)
}

const handleInput = (event: any) => {
  const text = event?.detail?.value
  const isAit = text.endsWith('@') || text.endsWith('@\n')
  if (props.scene == 'team') {
    if (isAit) {
      // 当前输入的是@
      uni.hideKeyboard()
      // @ts-ignore
      ctx.refs.popupRef.open('bottom')
      isFocus.value = false
      uni.$emit(events.HANDLE_MOVE_THROUGH, true)
    }
  }
}

const sendCustomMsg = (obj, msg) => {
  console.log(uni.$UIKitStore)
  const ext = onAtMembersExtHandler()
  uni.$UIKitStore.msgStore
    .sendCustomMsgActive({
      scene: props.scene as TMsgScene,
      to: props.to,
      body: msg || obj.body,
      attach: JSON.stringify(obj),
      type: 'custom',
      ext: selectedAtMembers.value.length && ext
    })
    .then(() => {
      if (extVisible.value) {
        extVisible.value = false
        uni.hideKeyboard()
      }
    })
  isReplyMsg.value = false
  selectedAtMembers.value = []
  uni.$emit(events.ON_SCROLL_BOTTOM)
}

const sendAudioMsg = (res) => {
  console.log(res)
  console.log(uni.$UIKitStore)

  uni.$UIKitStore.nim
    .sendAudioMsg({
      scene: props.scene as TMsgScene,
      to: props.to,
      filePath: res.tempFilePath,
      ext: JSON.stringify({
        duration: res.duration
      })
    })
    .then((res) => {
      console.log('-------------', res)
      let userInfoObj = uni.getStorageSync('userInfo')
        ? JSON.parse(uni.getStorageSync('userInfo')).patientInfo
        : {}
      sendNotice(userInfoObj.empi)

      uni.$UIKitStore.msgStore.addMsg(res.sessionId, [res])
      isReplyMsg.value = false
      selectedAtMembers.value = []
      uni.$emit(events.ON_SCROLL_BOTTOM)
    })

  // uni.$UIKitStore.msgStore.sendFileMsgActive({
  //   scene: props.scene as TMsgScene,
  //   to: props.to,
  //   filePath: res.tempFilePath
  // })
}

const sendImageMsg = (path) => {
  const ext = onAtMembersExtHandler()
  uni.$UIKitStore.msgStore
    .sendImageMsgActive({
      scene: props.scene as TMsgScene,
      to: props.to,
      filePath: path,
      ext: selectedAtMembers.value.length && ext
    })
    .then(() => {
      let userInfoObj = uni.getStorageSync('userInfo')
        ? JSON.parse(uni.getStorageSync('userInfo')).patientInfo
        : {}
      sendNotice(userInfoObj.empi)
      if (extVisible.value) {
        extVisible.value = false
        uni.hideKeyboard()
      }
    })
  isReplyMsg.value = false
  selectedAtMembers.value = []
  uni.$emit(events.ON_SCROLL_BOTTOM)
}

const handleSendTextMsg = () => {
  if (inputText.value === '') return
  if (inputText.value.trim() === '') {
    uni.showModal({
      content: '不能发送空白消息',
      showCancel: false,
      success: function (res) {
        if (res.confirm) {
          console.log('用户点击确定')
        }
      }
    })
    return
  }
  const ext = onAtMembersExtHandler()
  uni.$UIKitStore.msgStore
    .sendTextMsgActive({
      scene: props.scene as TMsgScene,
      to: props.to,
      body: inputText.value,
      ext: selectedAtMembers.value.length && ext
    })
    .then(() => {
      let userInfoObj = uni.getStorageSync('userInfo')
        ? JSON.parse(uni.getStorageSync('userInfo')).patientInfo
        : {}
      sendNotice(userInfoObj.empi)
      if (extVisible.value) {
        emojiVisible.value = false
        extVisible.value = false
        uni.hideKeyboard()
      }
    })
  inputText.value = ''
  isReplyMsg.value = false
  selectedAtMembers.value = []
  uni.$emit(events.ON_SCROLL_BOTTOM)
}

const removeReplyMsg = () => {
  uni.$UIKitStore.msgStore.removeReplyMsgActive(replyMsg?.value?.sessionId as string)
  isReplyMsg.value = false
}

const handleEmojiVisible = () => {
  if (isTeamMute.value) return
  if (uniPlatform == 'mp-weixin' || isAndroidApp) {
    setTimeout(() => {
      emojiVisible.value = true
      extVisible.value = true
    }, 300)
  } else {
    emojiVisible.value = true
    extVisible.value = true
  }
  showEmojiInput.value = true
  uni.$emit(events.HANDLE_MOVE_THROUGH, true)
}

const handleEmoji = (emoji: { key: string; type: string }) => {
  inputText.value += emoji.key
}

const handleEmojiDelete = () => {
  let target = ''
  const isEmojiEnd = Object.keys(emojiMap).reduce((prev, cur) => {
    const isEnd = inputText.value.endsWith(cur)
    if (isEnd) {
      target = cur
    }
    return prev || isEnd
  }, false)
  if (isEmojiEnd && target) {
    inputText.value = inputText.value.replace(target, '')
  } else {
    inputText.value = inputText.value.slice(0, -1)
  }
}

const handleSendImageMsg = () => {
  if (isTeamMute.value) return
  uni.chooseImage({
    count: 1,
    sizeType: ['compressed'],
    success: (res) => {
      if (res.tempFiles[0].size > 10 * 1024 * 1024) {
        uni.showToast({
          title: '文件大小超过上限',
          icon: 'error',
          duration: 2000
        })
        return
      }
      console.log(res)
      sendImageMsg(res.tempFilePaths[0])
      // upload(res.tempFilePaths[0])
      //   .then((r) => {
      //     console.log(r.data)
      //     const obj = {
      //       ...r.data,
      //       type: 'image',
      //       body: r.data.url
      //     }
      //     const msg = '[发送了一张图片]'
      //     sendCustomMsg(obj, msg)
      //     // sendingImg.value = true;
      //     // console.log(uni.$UIKitStore);
      //     // uni.$UIKitStore.nim
      //     //   .sendImageMsg({
      //     //     scene: props.scene as TMsgScene,
      //     //     to: props.to,
      //     //     attach: r.data
      //     //   })
      //     //   .catch((err) => {
      //     //     uni.showToast({
      //     //       icon: 'error',
      //     //       title: t('sendImageFailedText')
      //     //     });
      //     //   })
      //     //   .finally(() => {
      //     //     sendingImg.value = false;
      //     //     setTimeout(() => {
      //     //       uni.$emit(events.ON_SCROLL_BOTTOM);
      //     //     }, 100);
      //     //   });
      //   })
      //   .catch((e) => {
      //     uni.showToast({
      //       title: '图片上传失败，请检查网络后再尝试',
      //       icon: 'error',
      //       duration: 2000
      //     })
      //   })
    }
  })
}

const handleSendFileMsg = () => {
  uni.chooseFile({
    count: 1,
    success: (res) => {
      uni.$UIKitStore.msgStore.sendFileMsgActive({
        scene: props.scene as TMsgScene,
        to: props.to,
        filePath: res.tempFilePaths[0]
      })
    }
  })
}

const handleSetting = () => {
  if (props.scene === 'p2p') {
    customNavigateTo({
      url: `/pages/Chat/message/p2p-set?id=${props.to}`
    })
  } else if (props.scene === 'team') {
    customNavigateTo({
      url: `/pages/Group/group-set/index?id=${props.to}`
    })
  }
}

onMounted(() => {
  bus.on('im_video_stop_record', endRecord)

  // #ifndef H5
  recorderManager.onStop(function (res) {
    // const src = res.tempFilePath

    console.log('录音结束')
    audio.value.recording = false
    let endTime = Date.now()
    console.timeEnd('record')
    console.log(endTime - startTime.value)
    clearInterval(RecorderTimer)
    RecorderTimer = null
    let duration = endTime - startTime.value
    if (duration < 1000) {
      console.log('时间太短')
      uni.showToast({
        title: '录音时间太短',
        icon: 'none'
      })
      startTime.value = 0
    } else {
      console.log('时间够了')
      sendAudioMsg(res)
      startTime.value = 0
    }
  })
  // #endif

  // 撤回后，重新编辑消息
  uni.$on(events.ON_REEDIT_MSG, (msg: IMMessage) => {
    const _replyMsg = props.replyMsgsMap?.[msg.idClient]
    // 如果重新编辑的是回复消息，则需要将回复消息展示在输入框上方
    if (_replyMsg?.idClient) {
      _replyMsg && uni.$UIKitStore.msgStore.replyMsgActive(_replyMsg)
      replyMsg.value = _replyMsg
      isReplyMsg.value = true
    }
    // 如果重新编辑的是@消息，则需要将被@的成员重新加入selectedAtMembers
    if (msg.ext) {
      const extObj = JSON.parse(msg.ext)
      const yxAitMsg = extObj.yxAitMsg
      if (yxAitMsg) {
        const _mentionedMembers: MentionedMember[] = []
        Object.keys(yxAitMsg).forEach((key) => {
          if (key == 'ait_all') {
            _mentionedMembers.push({
              account: key,
              appellation: '所有人'
            })
          } else {
            _mentionedMembers.push({
              account: key,
              appellation: uni.$UIKitStore.uiStore.getAppellation({
                account: key,
                teamId: props.to,
                ignoreAlias: true
              })
            })
          }
        })
        selectedAtMembers.value = _mentionedMembers
      }
    }
    inputText.value = msg?.attach?.oldBody
    isFocus.value = true
  })

  uni.$on(events.REPLY_MSG, (msg: IMMessage) => {
    isReplyMsg.value = true
    isFocus.value = true
    replyMsg.value = msg
  })

  uni.$on(events.AIT_TEAM_MEMBER, (member) => {
    selectedAtMembers.value = [
      ...selectedAtMembers.value.filter((item) => item.account !== member.account),
      member
    ]
    const newInputText = inputText.value + '@' + member.appellation + ' '
    // 更新input框的内容
    inputText.value = newInputText
  })

  // 关闭表情面板
  uni.$on(events.CLOSE_EMOJI, () => {
    emojiVisible.value = false
    extVisible.value = false
    uni.$emit(events.HANDLE_MOVE_THROUGH, false)
  })

  // @消息 @群成员
  uni.$on(events.HANDLE_AIT_MEMBER, (member) => {
    handleMentionItemClick(member)
  })

  // 关闭@群成员面板
  uni.$on(events.CLOSE_AIT_POPUP, () => {
    closePopup()
  })

  // 表情点击
  uni.$on(events.EMOJI_CLICK, (emoji) => {
    handleEmoji(emoji)
  })

  // 表情删除
  uni.$on(events.EMOJI_DELETE, () => {
    handleEmojiDelete()
  })

  // 表情发送
  uni.$on(events.EMOJI_SEND, () => {
    emojiVisible.value = false
    extVisible.value = false
    handleSendTextMsg()
  })

  if (uni.onKeyboardHeightChange) {
    uni.onKeyboardHeightChange((res) => {
      const isAndroidApp = uni.getSystemInfoSync().platform == 'android' && uniPlatform == 'app'
      const isAndroidWxapp =
        uni.getSystemInfoSync().platform == 'android' && uniPlatform == 'mp-weixin'
      // 此处是为了点击安卓键盘上的收起按钮时，表情面板需要隐藏
      if ((res.height === 0 && isAndroidApp) || (res.height === 0 && isAndroidWxapp)) {
        emojiVisible.value = false
        extVisible.value = false
      }
    })
  }
})

const onAtMembersExtHandler = () => {
  let ext: any
  if (selectedAtMembers.value.length) {
    selectedAtMembers.value.forEach((member) => {
      // @ts-ignore
      const substr = `@${member.appellation}`
      const positions: number[] = []
      let pos = inputText.value.indexOf(substr)
      while (pos !== -1) {
        positions.push(pos)
        pos = inputText.value.indexOf(substr, pos + 1)
      }
      if (positions.length) {
        if (!ext) {
          ext = {
            yxAitMsg: {
              [member.account]: {
                text: substr,
                segments: []
              }
            }
          }
        } else {
          ext.yxAitMsg[member.account] = {
            text: substr,
            segments: []
          }
        }
        positions.forEach((position) => {
          const start = position
          ext.yxAitMsg[member.account].segments.push({
            start,
            end: start + substr.length,
            broken: false
          })
        })
      }
    })
  }
  return ext
}
autorun(() => {
  if (props.scene === 'team') {
    const team = uni.$UIKitStore.teamStore.teams.get(props.to)
    if (team?.mute) {
      const myUser = uni.$UIKitStore.userStore.myUserInfo
      const isGroupOwner = myUser?.account === team.owner
      const teamMembers = uni.$UIKitStore.teamMemberStore.getTeamMember(props.to)
      const isGroupManager = teamMembers
        .filter((item) => item.type === 'manager')
        .some((item) => item.account === myUser?.account)
      // 群主或者群管理员在群禁言时，可以发送消息
      if (isGroupOwner || isGroupManager) {
        isTeamMute.value = false
      } else {
        isTeamMute.value = team?.mute
      }
    } else {
      isTeamMute.value = false
    }
  }
})

onUnmounted(() => {
  bus.off('im_video_stop_record', endRecord)

  uni.$off(events.REPLY_MSG)
  uni.$off(events.ON_REEDIT_MSG)
  uni.$off(events.REPLY_MSG)
  uni.$off(events.AIT_TEAM_MEMBER)
  // 关闭表情面板
  uni.$off(events.CLOSE_EMOJI)
  // @消息 @群成员
  uni.$off(events.HANDLE_AIT_MEMBER)
  // 关闭@群成员面板
  uni.$off(events.CLOSE_AIT_POPUP)
  // 表情点击
  uni.$off(events.EMOJI_CLICK)
  // 表情删除
  uni.$off(events.EMOJI_DELETE)
  // 表情发送
  uni.$off(events.EMOJI_SEND)
  removeReplyMsg()
})
</script>

<style scoped lang="scss">
@import '../../styles/common.scss';

.recorder {
  flex: 1 1 auto;
  width: 100%;
  height: 32px;
  background: #fafafa;
  border-radius: 84px 84px 84px 84px;
  font-family: PingFang SC, PingFang SC;
  font-weight: 500;
  font-size: 30rpx;
  color: #222222;
  line-height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.recorder-active {
  background: #e0e0e0;
}

.recordering {
  position: fixed;
  top: 60%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 140px;
  height: 80px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.5);
  border-radius: 16px 16px 16px 16px;
  font-size: 14px;
  color: #fff;
  .img {
    width: 80px;
    height: 28px;
    background: url(@/static/record1.png) 0 0 no-repeat;
    background-size: 100% 100%;
    animation: tools 0.8s 0.2s infinite linear;
  }
}

@keyframes tools {
  0% {
    background: url(@/static/record1.png) 0 0 no-repeat;
    background-size: 100% 100%;
  }
  25% {
    background: url(@/static/record2.png) 0 0 no-repeat;
    background-size: 100% 100%;
  }
  50% {
    background: url(@/static/record3.png) 0 0 no-repeat;
    background-size: 100% 100%;
  }
  75% {
    background: url(@/static/record2.png) 0 0 no-repeat;
    background-size: 100% 100%;
  }
  100% {
    background: url(@/static/record1.png) 0 0 no-repeat;
    background-size: 100% 100%;
  }
}

.msg-input-wrapper {
  padding-bottom: constant(safe-area-inset-bottom);
  padding-bottom: env(safe-area-inset-bottom);
  flex: 1 1 auto;
  width: 100%;
  position: fixed;
  bottom: 0;
  left: 0;
  background-color: #eff1f3;
  transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
  z-index: 999;
  .msg-input {
    display: inline-flex;
    flex-direction: row;
    flex-wrap: nowrap;
    align-items: center;
    box-sizing: border-box;
  }
  .msg-input-wrap {
    flex: 1 1 auto;
    display: flex;
    display: flex;
    align-items: center;
    justify-content: center;
  }
}

.menu {
  padding: 48rpx 16rpx;
  .item {
    display: flex;
    flex-direction: column;
    align-items: center;
    .img {
      height: 112rpx;
      width: 112rpx;
    }
    .text {
      margin-top: 8rpx;
      font-weight: 400;
      font-size: 24rpx;
      color: #222222;
      line-height: 34rpx;
    }
  }
}

.msg-input {
  padding: 14rpx 20rpx;
  width: 100%;
  .img {
    flex: 0 0 auto;
    height: 32px;
    width: 32px;
    margin-left: 6px;
    display: inline-block;
    vertical-align: middle;
  }

  &-input {
    flex: 1 1 auto;
    background-color: #fff;
    height: 40px;
    line-height: 24rpx;
    min-height: 32px;
    font-size: 16rpx;
    border-radius: 6px;
  }
}

.msg-button-group {
  padding: 12px 20px 2px 20px;
  display: flex;
  flex-direction: row;
}

.msg-input-button {
  &:not(:last-child) {
    margin-right: 60px;
  }

  &.msg-input-loading {
    animation: loadingCircle 1s infinite linear;
    z-index: 1;
    width: 20px;
    height: 20px;
    margin-top: 4px;

    .loading {
      width: 100%;
      height: 100%;
    }
  }
}

.msg-ext {
  overflow-y: auto;
  width: 100%;
  height: 300px;
  background-color: #eff1f3;
  z-index: 1;
}

.reply-message-wrapper {
  display: flex;
  font-size: 13px;
  background-color: #eff1f2;
  height: 30px;
  padding-top: 6px;
  align-items: center;
  color: #929299;

  .reply-noFind {
    width: fit-content;
  }

  .reply-message-close {
    flex-basis: 14px;
    margin-left: 10px;
    display: flex;
    align-items: center;
  }

  .reply-message {
    display: flex;
    align-items: center;
    flex-basis: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .reply-title {
    flex-basis: 30px;
    white-space: nowrap;
    margin-right: 5px;
  }

  .reply-to {
    flex-basis: content;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 13px;
  }
}

.input-emoji {
  background-color: #fff;
  height: 40px;
  line-height: 40px;
  font-size: 16rpx;
  padding: 0 12px;
  border-radius: 6px;
}

.input-text {
  white-space: nowrap;
}

.input-placeholder {
  background-color: #fff;
  // height: 40px;
  line-height: 24rpx;
  font-size: 16rpx;
  // padding: 0 12px;
  border-radius: 6px;
  color: gray;
}
.msg-input {
  align-items: end;
}
.msg-input-inputs {
  max-height: 140px;
  width: 100%;
  padding: 6px;
  background: #fff;
  border-radius: 12rpx;
  .msg-input-input {
    width: 100%;
    max-height: 128px;
    overflow: hidden auto;
    box-sizing: border-box;
    font-size: 16px;
    min-height: initial;
    line-height: initial;
    ::placeholder {
      font-size: 16px;
    }
  }
}
</style>